package net;
import java.net.*;
import java.io.*;

import util.MessageInfo;

public class ClientSocket{
	private String ip;
	private int port;
	private Socket socket = null;
	DataOutputStream outStream = null;
	DataInputStream inStream = null;
	final int MESSAGE_BUFFER_LENGTH = 1024;
	final int MESSAGE_TYPE_LENGTH = 32;
	
	public ClientSocket(String ip, int port) {
		this.ip = ip;
		this.port = port;
	}

	public ClientSocket(Socket s, String ip, int port) {
		this.ip = ip;
		this.port = port;
		this.socket = s;
	}
	
	public boolean isNullSocket()
	{
		return socket == null ? true:false;
	}
	/** */
	/**
	 * create socket connection
	 * 
	 * @throws Exception
	 *             exception
	 */
	public void createConnection() throws Exception {
		try {
			socket = new Socket(ip, port);
		} catch (Exception e) {
			e.printStackTrace();
			if (socket != null)
			{
				socket.close();
				socket = null;
			}
			throw e;
		} finally {
		}
	}

	public void closeConnection() throws Exception {
		try {
			System.out.println("[ClientSocket][closeConnection]");
			if (outStream != null)
				outStream.close();
			if (inStream != null)
				inStream.close();
			if (socket != null)
				socket.close();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;

		} finally {
			outStream = null;
			inStream = null;
			socket = null;
		}
	}
	
	public void sendMessage(String sendMessage) throws Exception {
		try {
			System.out.println("[sendMessage] msg: " + sendMessage);
			 //Send the message to the server via output stream
			outStream = new DataOutputStream(socket.getOutputStream());
        	byte[] messageBuffer = new byte[MESSAGE_BUFFER_LENGTH];
        	byte[] message = sendMessage.getBytes();
        	System.arraycopy(message, 0, messageBuffer, 0, message.length);
        	outStream.write(messageBuffer);
        	outStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
			if (outStream != null)
				outStream.close();
			throw e;
		} finally {
		}
	}

	public String getMessage() throws Exception {
		String outMessage = null;
		try{
			inStream = new DataInputStream(socket.getInputStream());
		    byte[] messageBuffer = new byte[MESSAGE_BUFFER_LENGTH];

		    //Read the message from the server input stream
		    inStream.readFully(messageBuffer);
		    outMessage = new String(messageBuffer).trim();
			System.out.println("[getMessage] msg: " + outMessage);
		} catch (Exception e) {
			e.printStackTrace();
			if (inStream != null)
				inStream.close();
			throw e;
		}
		return outMessage;
	}
	public void sendMessageInfo(MessageInfo msgInfo) throws Exception {
		try {
			System.out.println("[sendMessageInfo] msg: [ " + msgInfo.getMsgType() + " ] " + msgInfo.getMsg());
			outStream = new DataOutputStream(socket.getOutputStream());
			// Write message type
			outStream.writeLong(msgInfo.getMsgType());
			// Write message text
        	byte[] messageBuffer = new byte[MESSAGE_BUFFER_LENGTH];
        	byte[] message = msgInfo.getMsg().getBytes();
        	System.arraycopy(message, 0, messageBuffer, 0, message.length);
        	outStream.write(messageBuffer);
        	outStream.flush();
        	
		} catch (Exception e) {
			e.printStackTrace();
			if (outStream != null)
				outStream.close();
			throw e;
		} finally {	
		}
	}
	public MessageInfo getMessageInfo() throws Exception {
		MessageInfo msgInfo;
		try {
			inStream = new DataInputStream(socket.getInputStream());
			long msgType = inStream.readLong();
			byte[] messageBuffer = new byte[MESSAGE_BUFFER_LENGTH];
			inStream.readFully(messageBuffer);
			String outMsg = new String(messageBuffer).trim();
			msgInfo = new MessageInfo(msgType, outMsg);
			System.out.println("[getMessageInfo] msg: [ " + msgType + " ] " + outMsg);
		} catch (Exception e) {
			e.printStackTrace();
			if (inStream != null)
				inStream.close();
			throw e;
		}
		return msgInfo;
	}
	public OutputStream getOutputStream() throws Exception {
		OutputStream out = null;
		try {
			if(socket != null)
				out =  socket.getOutputStream();
		}catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return out;
	}
	
	public InputStream getInputStream() throws Exception {
		InputStream in = null;
		try {
			if(socket != null)
				in = socket.getInputStream();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		return in;
	}
}
